package org.sws.domain.credit.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.sws.domain.credit.aggregate.TradeAggregate;
import org.sws.domain.credit.event.CreditAdjustSuccessMessageEvent;
import org.sws.domain.credit.model.entity.CreditAccountEntity;
import org.sws.domain.credit.model.entity.CreditOrderEntity;
import org.sws.domain.credit.model.entity.CreditTaskEntity;
import org.sws.domain.credit.model.entity.TradeEntity;
import org.sws.domain.credit.model.valobj.TradeNameVO;
import org.sws.domain.credit.model.valobj.TradeTypeVO;
import org.sws.domain.credit.repository.ICreditRepository;
import org.sws.types.enums.ResponseCode;
import org.sws.types.event.BaseEvent;
import org.sws.types.exception.AppException;

import java.math.BigDecimal;

/**
 * @Author sws
 * @Date 2025/4/1 15:48
 * @description:
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CreditAdjustService implements ICreditAdjustService{

    private final ICreditRepository creditRepository;
    private final CreditAdjustSuccessMessageEvent creditAdjustSuccessMessageEvent;
    @Override
    public String createCreditOrder(TradeEntity tradeEntity) {
        log.info("调整账户积分额度开始 userId:{} tradeName:{} amount:{}", tradeEntity.getUserId(), tradeEntity.getTradeName(), tradeEntity.getAmount());
        // 前置校验积分账户
        CreditAccountEntity queryUserCreditAccount = creditRepository.queryUserCreditAccount(tradeEntity.getUserId());
        if(null != queryUserCreditAccount && queryUserCreditAccount.getAvailableAmount().compareTo(BigDecimal.ZERO) <= 0 && TradeTypeVO.REVERSE.equals(tradeEntity.getTradeType()) && tradeEntity.getAmount().compareTo(BigDecimal.ZERO) < 0){
            throw new AppException(ResponseCode.CREDIT_ACCOUNT_SURPLUS_ERROR.getCode(), ResponseCode.CREDIT_ACCOUNT_SURPLUS_ERROR.getInfo());
        }
        // 1. 创建账户积分实体
        CreditAccountEntity creditAccountEntity = TradeAggregate.createCreditAccountEntity(
                tradeEntity.getUserId(),
                tradeEntity.getAmount());

        // 2. 创建账户订单实体
        CreditOrderEntity creditOrderEntity = TradeAggregate.createCreditOrderEntity(
                tradeEntity.getUserId(),
                tradeEntity.getTradeName(),
                tradeEntity.getTradeType(),
                tradeEntity.getAmount(),
                tradeEntity.getOutBusinessNo());

        // 3. 构建积分兑换消息任务对象，行为返利则无需发消息
        CreditTaskEntity creditTaskEntity = null;
        if(TradeNameVO.CONVERT_SKU.equals(tradeEntity.getTradeName())){
            CreditAdjustSuccessMessageEvent.CreditAdjustSuccessMessage creditAdjustSuccessMessage = new CreditAdjustSuccessMessageEvent.CreditAdjustSuccessMessage();
            creditAdjustSuccessMessage.setUserId(tradeEntity.getUserId());
            creditAdjustSuccessMessage.setCreditOrderId(creditOrderEntity.getCreditOrderId());
            creditAdjustSuccessMessage.setAmount(tradeEntity.getAmount());
            creditAdjustSuccessMessage.setOutBusinessNo(tradeEntity.getOutBusinessNo());
            BaseEvent.EventMessage<CreditAdjustSuccessMessageEvent.CreditAdjustSuccessMessage> creditAdjustSuccessMessageEventMessage = creditAdjustSuccessMessageEvent.buildEventMessage(creditAdjustSuccessMessage);
            creditTaskEntity = TradeAggregate.createTaskEntity(tradeEntity.getUserId(), creditAdjustSuccessMessageEvent.topic(), creditAdjustSuccessMessageEventMessage.getId(), creditAdjustSuccessMessageEventMessage);
        }

        // 4. 构建交易聚合对象
        TradeAggregate tradeAggregate = TradeAggregate.builder()
                .userId(tradeEntity.getUserId())
                .creditAccountEntity(creditAccountEntity)
                .creditOrderEntity(creditOrderEntity)
                .creditTaskEntity(creditTaskEntity)
                .build();

        // 5. 保存积分交易订单
        creditRepository.saveUserCreditTradeOrder(tradeAggregate);
        log.info("调整账户积分额度完成 userId:{} orderId:{}", tradeEntity.getUserId(), creditOrderEntity.getCreditOrderId());

        return creditOrderEntity.getCreditOrderId();
    }

    @Override
    public CreditAccountEntity queryUserCreditAccount(String userId) {
        return creditRepository.queryUserCreditAccount(userId);
    }
}
